using System.Collections.Generic;
using Imaginarium.team;
using GameEngine.Scenes;
using GameEngine.utils.console;
using GameEngine.utils;
using Imaginarium.Scenes;
namespace Imaginarium.battleSistem {
    public class TurnExpert
    {

        public BattleScene battleScene;
        BattleCommand currentCommand;
        public int turnCounter { get; set; }
        public int whichTeam { get; set; }
        public int currentCharacter { get; set; }
        public List<Team> m_Teams { get; set; }
        public bool readyToExecute { get; set; }

        public TurnExpert(BattleScene battleScene, List<Team> teams)
        {
            this.battleScene = battleScene;
            m_Teams = teams;
            turnCounter = 0;
            whichTeam = 0;
            readyToExecute = false;
        }
        public TurnExpert(BattleScene battleScene) :
            this(battleScene, new List<Team>())
        {
        }

        public bool isIAControlled()
        {
            if (m_Teams[whichTeam].teamController is IA.IATeam)
                return true;
            return false;
        }
        public Team getCurrentTeamInAction()
        {
            if (whichTeam >= m_Teams.Count) return null;
            return m_Teams[whichTeam];
        }
        public Character getCurrentCharacterInAction()
        {
            return getCurrentTeamInAction().characters[currentCharacter];
        }
        //Called after a character finished deciding their actions
        public void onCharacterTakenAction()
        {
            int prevCharIndex = currentCharacter;
            List<Character> characters = getCurrentTeamInAction().characters;
            currentCharacter++;
            while (currentCharacter < characters.Count && characters[currentCharacter].isDead()) //to skip died characters 
            {
                currentCharacter++;
            }
            if (currentCharacter >= characters.Count) //the team finished deciding it's moves
            {
                onTeamFinishedTakenAction();
                return;
            }
            battleScene.onCharacterFinishedTakingAction(characters[prevCharIndex], getCurrentCharacterInAction());
        }

        //Called after a whole team finished deciding their actions
        public void onTeamFinishedTakenAction()
        {
            currentCharacter = 0;
            whichTeam++;
            if (whichTeam >= m_Teams.Count) //all the teams have finished deciding it's moves
            {
                onTurnFinished();
                return;
            }
            battleScene.onTeamFinishedTakingAction(m_Teams[whichTeam - 1], m_Teams[whichTeam]);//let the battle scene know a team finished taking action
        }
        //Called after executing all actions
        public void onTurnFinished()
        {
            battleScene.onTeamFinishedTakingAction(m_Teams[whichTeam - 1], null); //let the battle scene know a team finished taking action
            whichTeam = 0;
            turnCounter++;
            readyToExecute = true;
        }

        public void setDefendCommand()
        {
            currentCommand = new DefendCommand(getCurrentCharacterInAction());
        }

        public Message setAbilityCommand(SkillDetail sd)
        {
            Message msg;
            if (sd.calcMPCost() > getCurrentCharacterInAction().mp)
            {
                msg = new Message(CodeParameters.notEnoughMP, false);
                return msg;
            }
            msg = new Message("", true);
            currentCommand = new AbilityCommand(getCurrentCharacterInAction(), null, sd);
            return msg;
        }

        public void setAttackCommand()
        {
            currentCommand = new AttackCommand(getCurrentCharacterInAction(), null);
        }

        public void setTargetCommand(Character c)
        {
            currentCommand.Target = c;
        }
        public void clearBattleCommand()
        {
            currentCommand = null;
        }
        public void startNewBattleCommand()
        {
            if (currentCommand != null)
            {
                BattleManager.getInstance().addToCommandStack(currentCommand);
            }
            clearBattleCommand();
        }

        public BattleOption.BattleOptionEnum getBattleCommandType()
        {
            return currentCommand.type;
        }
        public bool cancelLastCommand() {
            bool ans = false;
            if (currentCharacter <= 0) return ans;
            currentCharacter--;
            BattleManager.getInstance().removeLastCommand();
            clearBattleCommand();
            battleScene.setNextChar(getCurrentCharacterInAction());
            return ans;
        }
    }
}